#ifndef __GPUProcessingTesting__Experiment__
#define __GPUProcessingTesting__Experiment__

#include <iostream>
#include <fstream>
#include <vector>

#include "TrialsSet.h"
#include "Timer.h"

template <class T>
class Experiment {
public:
    typedef std::vector< TrialsSet<T> > TrialsSets;
    
    Experiment(const std::string& mainDescription, const std::string& fileName, const std::string& folderPath): mainDescription_(mainDescription), fileName_(fileName), folderPath_(folderPath) {}
    ~Experiment() {}
    
    void pushTrialsSet(TrialsSet<T> trialsSet) {
        trialsSets_.push_back(trialsSet);
    }
    void pushTrialsSet(Timers timer, std::string description) {
        
    }
    
    //Results 
    void writeToFile(bool ifEachTrialPrinted = false) {
        using namespace std;
        
        //Creating file for writing
        string filePath;
		filePath.append(folderPath_);
        filePath.append(fileName_);
		ofstream fs(filePath.c_str(), ios_base::out | ios_base::trunc);
		//.
        writeToStream(fs);
        fs.close();
    }
    void print(bool ifEachTrialPrinted = false) {
        writeToStream(std::cout, false);
    }
    
private:
    TrialsSets trialsSets_;
    
    const std::string mainDescription_;
    const std::string folderPath_, fileName_;
    
    static const std::string afterMainDescription_, afterTrialsSetDescription_, afterTrialsSet_;
    
    void writeToStream(std::ostream& outputStream, bool ifEachTrialPrinted = true) {
        
        //Writing to file
        outputStream << mainDescription_;
        outputStream << afterMainDescription_;
        
        unsigned long numberOfTrialsSet = trialsSets_.size();
        
        for(int i = 0; i < numberOfTrialsSet; ++i) {    //for each
            outputStream << trialsSets_[i].description_;
            if(ifEachTrialPrinted) {
                outputStream << afterTrialsSetDescription_;
                for(int j = 0; j < trialsSets_[i].trialsNumber_; ++j) {
                    outputStream << trialsSets_[i].trials_[j] << std::endl;
                }
            }
            outputStream << afterTrialsSet_;
        }
        outputStream << std::endl;
        //.
    }

};

template <class T> const std::string Experiment<T>::afterMainDescription_ = std::string     ("-------------------------------------\n\n\n\n");
template <class T> const std::string Experiment<T>::afterTrialsSetDescription_ = std::string("***\nTrials:\n");
template <class T> const std::string Experiment<T>::afterTrialsSet_ = std::string           ("***\n\n\n");


#endif /* defined(__GPUProcessingTesting__Experiment__) */